package com.free.mini.core.serve.service.impl;

import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.free.mini.common.base.ResultCode;
import com.free.mini.core.serve.entity.AdminUser;
import com.free.mini.core.serve.exception.CoreServiceException;
import com.free.mini.core.serve.mapper.AdminUserMapper;
import com.free.mini.core.serve.service.IAdminUserService;
import com.free.mini.core.serve.utils.IDGenerate;
import com.free.mini.core.server.vo.req.AdminUserLoginReqVO;
import com.free.mini.core.server.vo.req.AdminUserQueryDetailReqVO;
import com.free.mini.core.server.vo.req.AdminUserRegisterReqVO;
import com.free.mini.core.server.vo.resp.AdminUserLoginRespVO;
import com.free.mini.core.server.vo.resp.AdminUserQueryDetailRespVO;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.LRUCache;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.MD5;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author dongsufeng
 * @version 4.0
 * @date 2023/8/19 12:59
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements IAdminUserService {

    private final AdminUserMapper adminUserMapper;
    LRUCache<String, AdminUserLoginRespVO> loginCache = CacheUtil.newLRUCache(10);
    LRUCache<String, String> tokenCache = CacheUtil.newLRUCache(10);
    @Override
    public Boolean register(AdminUserRegisterReqVO reqVO) {
        LambdaQueryWrapper<AdminUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminUser::getLoginUserName,reqVO.getUsername());
        wrapper.last("limit 1");
        AdminUser adminUser = this.getOne(wrapper);
        if (ObjectUtil.isEmpty(adminUser)) {
            adminUser = BeanUtil.copyProperties(reqVO, AdminUser.class);
            adminUser.setAdminUserId(IDGenerate.idGenerate());
            adminUser.setLoginUserName(reqVO.getUsername());
            adminUser.setLoginPassword(MD5.create().digestHex(reqVO.getPassword()));
            adminUser.setLocked(0);
            if (StringUtils.isBlank(reqVO.getNickName())){
                adminUser.setNickName(reqVO.getUsername());
            }
            return this.save(adminUser);
        }
        return true;
    }

    @Override
    public AdminUserLoginRespVO login(AdminUserLoginReqVO reqVO) {
        if (ObjectUtil.isEmpty(reqVO) || StringUtils.isBlank(reqVO.getUsername())){
            throw new CoreServiceException(ResultCode.PARAM_ERROR);
        }
        LambdaQueryWrapper<AdminUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminUser::getLoginUserName,reqVO.getUsername());
        wrapper.last("limit 1");
        AdminUser user = this.getOne(wrapper);
        if (ObjectUtil.isEmpty(user)
                || !MD5.create().digestHex(reqVO.getPassword()).equalsIgnoreCase(user.getLoginPassword())){
            throw new CoreServiceException(ResultCode.USERNAME_PASSWD_ERR);
        }
        if (tokenCache.containsKey(user.getLoginUserName())){
            loginCache.remove(tokenCache.get(user.getLoginUserName()));
        }
        String accessToken = UUID.randomUUID().toString();
        AdminUserLoginRespVO respVO = BeanUtil.copyProperties(user, AdminUserLoginRespVO.class);
        respVO.setAccessToken(accessToken);
        tokenCache.put(user.getLoginUserName(), accessToken,1000*60*60);
        loginCache.put(accessToken,respVO,1000*60*60);
        return respVO;
    }
    @Override
    public AdminUserQueryDetailRespVO detail(AdminUserQueryDetailReqVO reqVO) {
        if (StringUtils.isBlank(reqVO.getLoginUserName()) && reqVO.getAdminUserId() == null){
            return null;
        }
        LambdaQueryWrapper<AdminUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(reqVO.getLoginUserName()),AdminUser::getLoginUserName,reqVO.getLoginUserName());
        wrapper.eq(reqVO.getAdminUserId() != null , AdminUser::getAdminUserId,reqVO.getAdminUserId());
        wrapper.last("limit 1");
        AdminUser user = this.getOne(wrapper);
        if (ObjectUtil.isNotEmpty(user)){
            return BeanUtil.copyProperties(user,AdminUserQueryDetailRespVO.class);
        }
        return null;
    }

}
